import geotrellis.proj4.{LatLng, WebMercator}
import geotrellis.raster.render.{ColorRamp, Jpg, Png, RGB}
import geotrellis.spark.tiling.LayoutDefinition
import geotrellis.spark.{SpatialKey, TileLayerRDD}
import geotrellis.vector.{Geometry, Line, MultiLine, Point}
import geotrellis.vector.io._
import sun.awt.image.PixelConverter.Rgba
Point(1,1).toGeoJson

MultiLine.EMPTY.union

abstract class Feature[D] {
  type G <: Geometry
  val geom: G
  val data: D
}
case class PointFeature[D](geom: Point, data: D) extends Feature[D]{type G = Point}


//颜色
import geotrellis.raster._
val hexColored: IntArrayTile = IntArrayTile.fill(0xFF0000FF, 100, 100)
val png: Png = hexColored.renderPng
val jpg: Jpg = hexColored.renderJpg

png.write("test.png")

//颜色坡度
val colorRamp =
  ColorRamp(
    RGB(0,255,0),
    RGB(63,255,51),
    RGB(102,255,102),
    RGB(178, 255,102),
    RGB(255,255,0),
    RGB(255,255,51),
    RGB(255,153, 51),
    RGB(255,128,0),
    RGB(255,51,51),
    RGB(255,0,0)
  )
//也可以定义颜色范围，然后中间有几个坡度
val colorRamp1 =
  ColorRamp(0xFF0000FF,0x0000FFFF)
    .stops(100)
    .setAlphaGradient(0xFF,0xAA)

//rgb 与 rgba
import geotrellis.raster.render._
val color1:Int = RGB(r = 255,g = 170,b = 85)
val color2:Int = RGBA(0xFF,0xAA,0x55,0xFF)
val color3:Int = 0xFFAA55FF
assert(color1 == color2 && color2 == color3)

//ColorMap 颜色映射，将颜色与Tile中的值对应
//colorMap的默认配置如下
val colorMapDefaultOptions =
  ColorMap.Options(
    // GreaterThan,
    // GreaterThanOrEqualTo,
    // LessThan,
    // LessThanOrEqualTo,
    // Exact
    classBoundaryType = LessThan,
    //无数据的颜色
    noDataColor = 0x000000000,
    //其他情况的颜色
    fallbackColor = 0x00000000,
    //如果配置为true，fallbackColor不会生效，并且出现意料之外的值将会抛出异常
    strict = false
  )
val colorMap1 =
  ColorMap(
    Map(
      3.5 -> RGB(0,255,0),
      7.5 -> RGB(63,255,51),
      11.5 -> RGB(102,255,102),
      15.5 -> RGB(178,255,102),
      19.5 -> RGB(255,255,0),
      23.5 -> RGB(255,255,51),
      26.5 -> RGB(255,153,51),
      31.5 -> RGB(255,128,0),
      35.0 -> RGB(255,51,51),
      40.0 -> RGB(255,0,0)
    )
  )
val colorMap2 =
  ColorMap(
    Map(
      3.5 -> RGB(0,255,0),
      7.5 -> RGB(63,255,51),
      11.5 -> RGB(102,255,102),
      15.5 -> RGB(178,255,102),
      19.5 -> RGB(255,255,0),
      23.5 -> RGB(255,255,51),
      26.5 -> RGB(255,153,51),
      31.5 -> RGB(255,128,0),
      35.0 -> RGB(255,51,51),
      40.0 -> RGB(255,0,0)
    ),
    ColorMap.Options(
      classBoundaryType = GreaterThanOrEqualTo,
      noDataColor = 0xFFFFFFFF,
      fallbackColor = 0xFFFFFFFF
    )
  )

colorMap1.mapDouble(2.0) == RGB(0,255,0)
colorMap2.mapDouble(2.0) == 0xFFFFFFFF

//创建基于直方图的ColorMap
val input = Array[Double](
  NODATA, 7, 1, 1, 3, 5, 9, 8, 2,
  9, 1, 1, 2, 2, 2, 4, 3, 5,
  3, 8, 1, 3, 3, 3, 1, 2, 2,
  2, 4, 7, 1, NODATA, 1, 8, 4, 3
)
val tile: Tile = DoubleArrayTile(input,9,4)
val colorMap3 = ColorMap
  .fromQuantileBreaks(
    tile.histogram,
    ColorRamp(0xFF0000FF,0x0000FFFF)
      .stops(10)
)
//或者使用
val colorMap4:ColorMap =
  ColorRamp(0xFF0000FF, 0x0000FFFF)
    .stops(10)
    .toColorMap(tile.histogram)


//重投影
//矢量（point，line，面）
val wm:Line = Line(Point(0,0),Point(1,1))
val ll: Line = wm.reproject(WebMercator, LatLng)
//Extent投影如上
//图片重投影
val wm1: TileLayerRDD[SpatialKey] = ???
val layout: LayoutDefinition = ???
val (zoom,ll2):(Int, TileLayerRDD[SpatialKey]) = wm1.reproject(LatLng, layout)


//etl
val inputJson =
  """
    |[{
    |  "format": "geotiff", // geotiff/temporal-geotiff
    |  "name": "test",
    |  "cache": "NONE",
    |  "noData": 0.0,     // nodata的值
    |  "clip": {
    |    "xmin":1.0,
    |    "ymin":2.0,
    |    "xmax":3.0,
    |    "ymax":4.0
    |  },
    |  "backend": {
    |    "type": "hadoop",
    |    "path": "input"
    |  }
    |}]
    |format	Format of the tile files to be read (ex: geotiff)
    |name	Input dataset name
    |cache	Spark RDD cache strategy
    |noData	NoData value
    |clip	Extent in target CRS to clip the input source
    |crs	Destination crs name (example: EPSG:3857) (optional field)
    |maxTleSize	Inputs will be broken up into smaller tiles of the given size (optional field)(example: 256 returns 256x256 tiles)
    |numPartitions	How many partitions Spark should make when repartioning (optional field)
    |"""

val outputJson =
  """
    |{
    |   "backend":{  //存储到哪里
    |      "type":"accumulo",
    |      "path":"output",
    |      "profile":"accumulo-name"
    |   },
    |   "breaks":"0:ffffe5ff;0.1:f7fcb9ff;0.2:d9f0a3ff;0.3:addd8eff;", //颜色映射
    |   "reprojectMethod":"buffered", //重映射的存放方式
    |   "cellSize":{        //单元格大小
    |      "width":256.0,
    |      "height":256.0
    |   },
    |   "encoding":"geotiff",  //输出格式 png/geotiff
    |   "tileSize":256,         //tile数量，256*256
    |   "layoutExtent":{
    |      "xmin":1.0,
    |      "ymin":2.0,
    |      "xmax":3.0,
    |      "ymax":4.0
    |   },
    |   "tileLayout":{
    |       "layoutCols": 360,
    |       "layoutRows": 180,
    |       "tileCols":   240,
    |       "tileRows":   240
    |    },
    |   "resolutionThreshold":0.1,
    |   "pyramid":true,
    |   "resampleMethod":"nearest-neighbor",  //金字塔化的方法
    |   "keyIndexMethod":{          //索引方案
    |      "type":"zorder"
    |   },
    |   "layoutScheme":"zoomed",  //多层 zoomed/floating
    |   "cellType":"int8", //单元类型
    |   "crs":"EPSG:3857"
    |}
    |说明
    |backend	Backend description is presented below
    |breaks	Breaks string for render output (optional field)
    |partitions	Partitions number during pyramid build
    |reprojectMethod	buffered, per-tile
    |cellSize	Cell size
    |encoding	png, geotiff for render output
    |tileSize	Tile size (optional field)If not set, the default size of output tiles is 256x256
    |layoutExtent	Layout extent (optional field)
    |tileLayout	Tile layout to specify layout grid (optional field)
    |resolutionThreshold	Resolution for user defined Layout Scheme (optional field)
    |pyramid	true, false - ingest with or without building a pyramid
    |resampleMethod	nearest-neighbo r, bilinear, cubic-convoluti on, cubic-spline, lanczos
    |keyIndexMethod	zorder, row-major, hilbert
    |layoutScheme	tms, floating (optional field)
    |cellType	int8, int16, etc… (optional field)
    |crs	Destination crs name (example: EPSG:3857) (optional field)
  """
